package bch.netty;



import bch.netty.handler.GlobalExceptionHandler;
import bch.netty.handler.TextWebSocketServerInboundHandler;
import bch.netty.handler.inbound.InboundHandlerA;
import bch.netty.handler.inbound.InboundHandlerB;
import bch.netty.handler.outbound.OutBoundHandlerA;
import bch.netty.handler.outbound.OutBoundHandlerB;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * @author DCJ
 * SimpleChannelInboundHandler 是按照顺序执行的
 * ChannelOutboundHandler 是按照倒序执行的
 */
@Component
@RequiredArgsConstructor
public class WebSocketServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    private final TextWebSocketServerInboundHandler textWebSocketServerInboundHandler;

    @Override
    protected void initChannel(SocketChannel ch) {
        ChannelPipeline pipeline = ch.pipeline();


        // 双向链表的指针操作
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new ChunkedWriteHandler());
        pipeline.addLast(new HttpObjectAggregator(8192));

        // WebSocket
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
        // 心跳检测
        pipeline.addLast(new IdleStateHandler(120, 0, 0));
        // 日志
        pipeline.addLast(new LoggingHandler("ChildLoggingHandler", LogLevel.INFO));

        pipeline.addLast(new InboundHandlerB());
        pipeline.addLast(textWebSocketServerInboundHandler);
        pipeline.addLast(new InboundHandlerA());

        pipeline.addLast(new OutBoundHandlerA());
        pipeline.addLast(new OutBoundHandlerB());

        // 最后一个添加的handler是全局异常处理器
        pipeline.addLast(new GlobalExceptionHandler());


    }
}
